<template>
  <div style="width: 360px; margin: 0 auto">
    <a-card>
      <template #title>
        <div class="tac">请您登录</div>
      </template>
      <a-form>
        <a-form-item>
          <a-input v-model.trim="username" size="large" type="text" placeholder="用户名">
            <a-icon slot="prefix" type="user" :style="{ color: 'rgba(0,0,0,.25)' }" />
          </a-input>
        </a-form-item>

        <a-form-item>
          <a-input-password @keyup.enter="handleLogin()" v-model.trim="password" size="large" placeholder="密码">
            <a-icon slot="prefix" type="lock" :style="{ color: 'rgba(0,0,0,.25)' }" />
          </a-input-password>
        </a-form-item>

        <a-form-item v-if="showCaptcha">
          <a-row :gutter="10">
            <a-col span="16">
              <a-input
                v-model.trim="captcha"
                size="large"
                type="text"
                placeholder="请输入验证码"
                @pressEnter="handleLogin"
              >
                <a-icon slot="prefix" type="picture" :style="{ color: 'rgba(0,0,0,.25)' }" />
              </a-input>
            </a-col>
            <a-col span="8">
              <img
                @click="getCaptcha()"
                class="wfull h40 cpt pos-rlt"
                style="top: -2px"
                :src="`data:image/png;base64,${captchaImg}`"
              />
            </a-col>
          </a-row>
        </a-form-item>

        <a-form-item>
          <a-button
            size="large"
            type="primary"
            style="width: 100%"
            :loading="doing"
            :disabled="doing"
            @click="handleLogin"
          >登录</a-button
          >
        </a-form-item>
        <a-form-item style="margin-bottom: 0">
          <div class="wfull flx-e">
            <a-button type="link" @click="findPwd">忘记密码？</a-button>
          </div>
        </a-form-item>
      </a-form>
    </a-card>
    <ZgDialog v-model="findPwdVisible" width="25%" top="25%" title="密码找回" @cancel="cancel">
      <a-form-model ref="form" :model="form" :rules="rules" :labelCol="labelCol" :wrapperCol="wrapperCol">
        <a-form-model-item label="用户名" prop="username">
          <ZgInput v-model="form.username" placeholder="请输入用户名"></ZgInput>
        </a-form-model-item>
        <a-form-model-item label="手机号" prop="telephone">
          <ZgInput v-model="form.telephone" placeholder="请输入手机号"></ZgInput>
        </a-form-model-item>
        <a-form-model-item label="验证码" prop="verifyCode">
          <a-row :gutter="20">
            <a-col :span="12">
              <ZgInput v-model="form.verifyCode" placeholder="请输入验证码" @enter="verifyCode"></ZgInput>
            </a-col>
            <a-col :span="1" style="padding-left: 0">
              <a-icon type="check" style="color: green" v-if="verifyCodePass" />
            </a-col>
            <a-col :span="9">
              <ZgButton
                type="primary"
                icon=""
                style="width: 117px"
                :loading="verifyCodeLoading"
                :disabled="!teleValidPass || waiting"
                @click="getVerifyCode"
              >{{ waiting ? captchaCountdown + 's' : '获取验证码' }}</ZgButton
              >
            </a-col>
          </a-row>
        </a-form-model-item>
        <a-form-model-item label="新密码" prop="newPwd">
          <ZgPassword v-model="form.newPwd" placeholder="8位以上包含数字字母符号" :disabled="!verifyCodePass" />
        </a-form-model-item>
        <a-form-model-item label="确认密码" prop="confirmPwd">
          <ZgPassword v-model="form.confirmPwd" placeholder="8位以上包含数字字母符号" :disabled="!verifyCodePass" />
        </a-form-model-item>
      </a-form-model>
      <div class="footer" slot="footer">
        <a-button type="primary" @click="save">确定</a-button>
      </div>
    </ZgDialog>
  </div>
</template>

<script>
import { mapActions } from 'vuex'
export default {
  data() {
    return {
      showCaptcha: true,
      doing: false,
      username: '',
      password: '',
      captcha: '',
      captchaSign: '',
      captchaImg: '',
      // 密码找回
      findPwdVisible: false,
      form: {
        username: undefined,
        telephone: undefined,
        verifyCode: undefined,
        newPwd: undefined,
        confirmPwd: undefined
      },
      labelCol: { span: 6 },
      wrapperCol: { span: 18 },
      rules: {
        username: [{ required: true, message: '请输入用户名', trigger: 'change' }],
        telephone: [
          { required: true, message: '请输入手机号', trigger: 'change' },
          {
            validator: this.teleValidate,
            trigger: 'change'
          }
        ],
        verifyCode: [
          { required: true, message: '请输入验证码', trigger: 'change' },
          {
            validator: this.verifyCodeValidate
          }
        ],
        newPwd: [
          { required: true, message: '请输入密码', trigger: 'change' },
          { min: 8, message: '密码长度不能小于8位', trigger: 'change' },
          { validator: this.pwdValidate, trigger: 'change' }
        ],
        confirmPwd: [
          { required: true, message: '请再次输入密码', trigger: 'change' },
          { validator: this.confirmPwdValidate, trigger: 'change' }
        ]
      },
      teleValidPass: false,
      verifyCodePass: false, // 短信验证码验证通过
      verifyCodeLoading: false,
      verifyId: null, // 发送短信验证码后返回的id
      waiting: false, // 发送验证码之后一段时间内不能再次发送
      timer: null,
      captchaCountdown: 120 // 倒计时总数
    }
  },
  mounted() {
    this.getCaptcha()
  },
  methods: {
    ...mapActions(['login']),
    handleLogin() {
      if (this.username.length === 0) {
        this.$warning({ title: '请输入用户名' })
        return
      }
      if (this.password.length === 0) {
        this.$warning({ title: '请输入密码' })
        return
      }
      if (this.showCaptcha) {
        if (this.captcha.length === 0) {
          this.$warning({ title: '请输入验证码' })
          return
        }
      }
      this.doing = true
      if (!this.showCaptcha) {
        this.login({
          username: this.username,
          password: this.genPwd(this.password)
        })
          .then((res) => this.loginSuccess(res))
          .catch(() => this.loginError())
          .finally(() => {
            this.doing = false
          })
      } else {
        this.$http.get('zg-system/un/captcha/validate', { sign: this.captchaSign, captcha: this.captcha }, (data) => {
          if (!data) {
            this.doing = false
            this.$warning({ title: '请输入正确的验证码' })
          } else {
            this.login({
              username: this.username,
              password: this.genPwd(this.password)
            })
              .then((res) => {
                this.loginSuccess(res)
              })
              .catch(() => this.loginError())
              .finally(() => {
                this.doing = false
              })
          }
        })
      }
    },
    getCaptcha() {
      this.$http.get('zg-system/un/captcha/create', {}, (data) => {
        this.captchaImg = data[1]
        this.captchaSign = data[0]
      })
    },
    loginSuccess(res) {
      if (res && res.code === 1) {
        window.location.reload()
        // this.$router.push({ path: '/' })
      }
    },
    loginError() {
      this.$notification.error({
        message: '错误',
        description: '请求出现错误，请稍后再试',
        duration: 2
      })
    },
    // 找回密码
    findPwd() {
      this.findPwdVisible = true
    },
    // 电话号码验证
    teleValidate(rule, value, callback) {
      const mobileRegex = /^1[3-9]\d{9}$/
      if (!value) {
        this.teleValidPass = false
        callback(new Error('请输入手机号'))
      } else if (!mobileRegex.test(value)) {
        this.teleValidPass = false
        callback(new Error('请输入正确的手机号格式'))
      } else {
        this.teleValidPass = true
        callback()
      }
    },
    // 新密码验证
    pwdValidate(rule, value, callback) {
      const regex = /^(?=.*\d)(?=.*[a-zA-Z])(?=.*[!@#$%^&*]).{8,}$/
      if (!value.length) {
        callback(new Error('请输入密码'))
      } else if (!regex.test(value)) {
        callback(new Error('密码格式不正确'))
      } else {
        callback()
      }
    },
    // 再次输入密码验证
    confirmPwdValidate(rule, value, callback) {
      if (!value.length) callback(new Error('请再次输入密码'))
      else if (value !== this.form.newPwd) callback(new Error('两次输入的密码不一致'))
      else callback()
    },
    // 获取验证码
    getVerifyCode() {
      this.verifyCodeLoading = true
      this.$http.post(
        '/zg-message/message/info/add',
        {
          receiverAdd: this.form.telephone,
          templateId: '1925754947531407362',
          title: '获取短信验证码',
          sender: '用户找回密码'
        },
        (data) => {
          Object.assign(this, {
            waiting: true,
            verifyCodeLoading: false,
            verifyId: data
          })
          this.startCountDown()
        }
      )
    },
    // 开启倒计时
    startCountDown() {
      this.timer = setInterval(() => {
        if (this.captchaCountdown > 0) this.captchaCountdown -= 1
        else {
          this.waiting = false
          clearInterval(this.timer)
        }
      }, 1000)
    },
    // 验证验证码是否正确
    verifyCode() {
      const { form, verifyId } = this
      const { verifyCode } = form
      if (!verifyCode || !verifyId) return
      this.$http.post(
        '/zg-message/message/info/verify',
        {
          code: verifyCode,
          id: verifyId
        },
        (data) => {
          if (data) this.verifyCodePass = true
          this.$refs.form.validateField('verifyCode')
        }
      )
    },
    verifyCodeValidate(rule, value, callback) {
      if (!this.verifyCodePass) callback(new Error('验证码错误'))
      else callback()
    },
    save() {
      const { username, telephone, verifyCode, newPwd, confirmPwd } = this.form
      this.$refs.form.validate((valid) => {
        if (valid) {
          this.$http.post(
            'zg-system/un/user/updatePwd',
            {
              userName: username,
              phone: telephone,
              verifyCode,
              passWord: newPwd,
              newPassWord: confirmPwd
            },
            (data) => {
              if (data) {
                this.$message.success('密码修改成功')
                this.findPwdVisible = false
                this.cancel()
              }
            }
          )
        }
      })
    },
    cancel() {
      this.verifyCodeLoading = this.waiting = this.verifyCodePass = false
      this.verifyId = null
      this.captchaCountdown = 120
      this.$refs.form.resetFields()
      if (this.timer) {
        clearInterval(this.timer)
        this.timer = null
      }
    }
  }
}
</script>

<style lang="less" scoped></style>
